package com.share.thread;

/**
 * @desc: 转账死锁示例
 * @author:caifan
 * @date:2022/4/7
 */
public class DeadLockTransferMoney implements Runnable {
    private int flag;
    static Account a = new Account(500);
    static Account b = new Account(500);

    public static void main(String[] args) throws InterruptedException {
        DeadLockTransferMoney r1 = new DeadLockTransferMoney();
        DeadLockTransferMoney r2 = new DeadLockTransferMoney();
        r1.flag = 1;
        r2.flag = 2;
        Thread t1 = new Thread(r1);
        Thread t2 = new Thread(r2);
        t1.start();
        t2.start();
        t1.join();
        t2.join();
        System.out.println("a余额:" + a.balance);
        System.out.println("b余额:" + b.balance);
    }

    @Override
    public void run() {
        if (flag == 1) {
            transerMoney(a, b, 200);
        }
        if (flag == 2) {
            transerMoney(b, a, 100);
        }
    }

    /**
     * 转账
     * @param from 付款
     * @param to 收款
     * @param amount 金额
     */
    public void transerMoney(Account from, Account to, int amount) {
        // 通过hashcode值来解决死锁问题
        int fromHashcode = System.identityHashCode(from);
        int toHashcode = System.identityHashCode(to);
        System.out.println("fh:" + fromHashcode + ", th:" + toHashcode);
        if (fromHashcode < toHashcode) {
            synchronized (from) {
                try {
                    Thread.sleep(500);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                synchronized (to) {
                    if (from.balance - amount < 0) {
                        System.out.println("余额不足，转账失败");
                    }
                    from.balance = from.balance - amount;
                    to.balance = to.balance + amount;
                    System.out.println("成功转账" + amount + "元");
                }
            }
        } else if (fromHashcode > toHashcode) {
            synchronized (to) {
                try {
                    Thread.sleep(500);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                synchronized (from) {
                    if (from.balance - amount < 0) {
                        System.out.println("余额不足，转账失败");
                    }
                    from.balance = from.balance - amount;
                    to.balance = to.balance + amount;
                    System.out.println("成功转账" + amount + "元");
                }
            }
        }
    }

    static class Account {
        int balance;
        public Account(int balance) {
            this.balance = balance;
        }
    }
}
